home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 014 / termcap / tgoto.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  6KB  |  248 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1982, Fred Fish            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  *    This software and/or documentation is released for public    *
  7.  *    distribution for personal, non-commercial use only.        *
  8.  *    Limited rights to use, modify, and redistribute are hereby    *
  9.  *    granted for non-commercial purposes, provided that all        *
  10.  *    copyright notices remain intact and all changes are clearly    *
  11.  *    documented.  The author makes no warranty of any kind with    *
  12.  *    respect to this product and explicitly disclaims any implied    *
  13.  *    warranties of merchantability or fitness for any particular    *
  14.  *    purpose.                            *
  15.  *                                    *
  16.  ************************************************************************
  17.  */
  18.  
  19.  
  20. /*
  21.  *  LIBRARY FUNCTION
  22.  *
  23.  *    tgoto   expand cursor addressing string from cm capability
  24.  *
  25.  *  KEY WORDS
  26.  *
  27.  *    termcap
  28.  *
  29.  *  SYNOPSIS
  30.  *
  31.  *    char *tgoto(cm,destcol,destline)
  32.  *    char *cm;
  33.  *    int destcol;
  34.  *    int destline;
  35.  *
  36.  *  DESCRIPTION
  37.  *
  38.  *    Returns cursor addressing string, decoded from the cm
  39.  *    capability string, to move cursor to column destcol on
  40.  *    line destline.
  41.  *
  42.  *    The following sequences uses one input argument, either
  43.  *    line or column, and place the appropriate substitution
  44.  *    in the output string:
  45.  *
  46.  *        %d    substitute decimal value (in ASCII)
  47.  *        %2    like %d but forces field width to 2
  48.  *        %3    like %d but forces field width to 3
  49.  *        %.    like %c
  50.  *        %+x    like %c but adds ASCII value of x
  51.  *
  52.  *    The following sequences cause processing modifications
  53.  *    but do not "use up" one of the arguments.  If they
  54.  *    act on an argument they act on the next one to
  55.  *    be converted.
  56.  *
  57.  *        %>xy    if next value to be converted is
  58.  *            greater than value of ASCII char x
  59.  *            then add value of ASCII char y.
  60.  *        %r    reverse substitution of line
  61.  *            and column (line is substituted
  62.  *            first by default).
  63.  *        %i    causes input values destcol and
  64.  *            destline to be incremented.
  65.  *        %%    gives single % character in output.
  66.  *
  67.  *  BUGS
  68.  *
  69.  *    Does not implement some of the more arcane sequences for
  70.  *    radically weird terminals (specifically %n, %B, & %D).
  71.  *    If you have one of these you deserve whatever happens.
  72.  *
  73.  */
  74.  
  75. /*
  76.  *    Miscellaneous stuff
  77.  */
  78.  
  79. #include <stdio.h>
  80.  
  81. #define MAXARGS 2
  82.  
  83. static char *in;        /* Internal copy of input string pointer */
  84. static char *out;        /* Pointer to output array */
  85. static int args[MAXARGS];    /* Maximum number of args to convert */
  86. static int pcount;        /* Count of args processed */
  87. static char output[64];        /* Converted string */
  88.  
  89.  
  90. /*
  91.  *  PSEUDO CODE
  92.  *
  93.  *    Begin tgoto
  94.  *        If no string to process then
  95.  *        Return pointer to error string.
  96.  *        Else
  97.  *        Initialize pointer to input string.
  98.  *        Initialize pointer to result string.
  99.  *        First arg is line number by default.
  100.  *        Second arg is col number by default.
  101.  *        No arguments processed yet.
  102.  *        While there is another character to process
  103.  *            If character is a not a % character then
  104.  *            Simply copy to output.
  105.  *            Else
  106.  *            Process the control sequence.
  107.  *            End if
  108.  *        End while
  109.  *        Return pointer to static output string.
  110.  *        End if
  111.  *    End tgoto
  112.  *
  113.  */
  114.  
  115. char *tgoto(cm,destcol,destline)
  116. char *cm;
  117. int destcol;
  118. int destline;
  119. {
  120.     if (cm == NULL) {
  121.     return("OOPS");
  122.     } else {
  123.     in = cm;
  124.     out = output;
  125.     args[0] = destline;
  126.     args[1] = destcol;
  127.     pcount = 0;
  128.     while (*in != NULL) {
  129.         if (*in != '%') {
  130.         *out++ = *in++;
  131.         } else {
  132.         process();
  133.         }
  134.     }
  135.     return(output);
  136.     }
  137. }
  138.  
  139. /*
  140.  *  INTERNAL FUNCTION
  141.  *
  142.  *    process   process the conversion/command sequence
  143.  *
  144.  *  SYNOPSIS
  145.  *
  146.  *    static process()
  147.  *
  148.  *  DESCRIPTION
  149.  *
  150.  *    Processes the sequence beginning with the % character.
  151.  *    Directly manipulates the input string pointer, the
  152.  *    output string pointer, and the arguments.  Leaves
  153.  *    the input string pointer pointing to the next character
  154.  *    to be processed, and the output string pointer pointing
  155.  *    to the next output location.  If conversion of
  156.  *    one of the numeric arguments occurs, then the pcount
  157.  *    is incremented.
  158.  *
  159.  */
  160.  
  161. /*
  162.  *  PSEUDO CODE
  163.  *
  164.  *    Begin process
  165.  *        Skip over the % character.
  166.  *        Switch on next character after %
  167.  *        Case 'd':
  168.  *        Process %d type conversion (variable width).
  169.  *        Reinitialize output pointer.
  170.  *        Break;
  171.  *        Case '2':
  172.  *        Process %d type conversion (width 2).
  173.  *        Reinitialize output pointer.
  174.  *        Break;
  175.  *        Case '3':
  176.  *        Process %d type conversion (width 3).
  177.  *        Reinitialize output pointer.
  178.  *        Break;
  179.  *        Case '.'
  180.  *        Process %c type conversion.
  181.  *        Break;
  182.  *        Case '+':
  183.  *        Process %c type conversion with offset.
  184.  *        Break;
  185.  *        Case '>':
  186.  *        Process argument modification.
  187.  *        Break;
  188.  *        Case 'r':
  189.  *        Process argument reversal.
  190.  *        Break;
  191.  *        Case 'i':
  192.  *        Increment argument values.
  193.  *        Break;
  194.  *        Case '%':
  195.  *        Copy to output, incrementing pointers.
  196.  *        Break;
  197.  *        End switch
  198.  *    End process
  199.  *
  200.  */
  201.  
  202.  
  203. static process()
  204. {
  205.     int temp;
  206.  
  207.     in++;
  208.     switch(*in++) {
  209.     case 'd':
  210.     sprintf(out,"%d",args[pcount++]);
  211.     out = &output[strlen(output)];    
  212.     break;
  213.     case '2':
  214.     sprintf(out,"%02d",args[pcount++]);
  215.     out = &output[strlen(output)];
  216.     break;
  217.     case '3':
  218.     sprintf(out,"%03d",args[pcount++]);
  219.     out = &output[strlen(output)];
  220.     break;
  221.     case '.':
  222.     *out++ = args[pcount++];
  223.     break;
  224.     case '+':
  225.     *out++ = args[pcount++] + *in++;
  226.     break;
  227.     case '>':
  228.     if (args[pcount] > *in++) {
  229.         args[pcount] += *in++;
  230.     } else {
  231.         in++;
  232.     }
  233.     break;
  234.     case 'r':
  235.     temp = args[pcount];
  236.     args[pcount] = args[pcount+1];
  237.     args[pcount+1] = temp;
  238.     break;
  239.     case 'i':
  240.     args[pcount]++;
  241.     args[pcount+1]++;
  242.     break;
  243.     case '%':
  244.     *out++ = '%';
  245.     break;
  246.     }
  247. }
  248.